/*   **********************************************************************  **
 **   Copyright notice                                                       **
 **                                                                          **
 **   (c) 2009, Around(J2)ME				                                 **
 **   All rights reserved.                                                   **
 **                                                                          **
 **   This program and the accompanying materials are made available under   **
 **   the terms of the New BSD License which accompanies this    			 **
 **   distribution.											                 **
 **   A copy is found in the textfile LICENSE.txt							 **
 **                                                                          **
 **   This copyright notice MUST APPEAR in all copies of the file!           **
 **                                                                          **
 **   Main developers:                                                       **
 **     Juri Strumpflohner		http://blog.js-development.com	             **
 **		Matthias Braunhofer		http://matthias.jimdo.com                    **
 **                                                                          **
 **  **********************************************************************  */

package org.aroundme.services;

import java.util.ArrayList;
import java.util.List;

import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
import org.apache.lucene.document.Field.Index;
import org.apache.lucene.document.Field.Store;
import org.apache.solr.util.NumberUtils;
import org.aroundme.model.Category;
import org.aroundme.model.Place;

/**
 * This class is responsible for converting a Place object into a Lucene Document object
 */
public class PlaceDocument {
	private Document document;
	private Place place;

	public static final String ID = "id";
	public static final String LATITUDE = "lat";
	public static final String LONGITUDE = "lng";
	public static final String CATEGORIES = "categories";
	public static final String ALL = "all";

	public PlaceDocument(Place place) {
		this.place = place;
		document = new Document();
	}

	public Place getPlace() {
		return place;
	}

	public Document getDocument() {
		return document;
	}

	/**
	 * adds values of a Place object as fields to the Document object
	 * @return
	 */
	public boolean addFields() {
		List<Field> fields = new ArrayList<Field>();

		/* Add ID */
		addField(fields, createDocumentIDField());

		/* Add coordinates */
		addField(fields, createStringField(LATITUDE, NumberUtils.double2sortableStr(place.getLocation().getLat()), Store.NO, Index.UN_TOKENIZED));
		addField(fields, createStringField(LONGITUDE, NumberUtils.double2sortableStr(place.getLocation().getLon()), Store.NO, Index.UN_TOKENIZED));

		/* Add categories */
		for (Category category : place.getCategories()) {
			addField(fields, createStringField(CATEGORIES, category.getName(), Store.NO, Index.UN_TOKENIZED));
		}
		
		/* Add a single searchable field to support full-text search */
		addField(fields, createStringField(ALL, place.getName(), Store.NO, Index.TOKENIZED));
		addField(fields, createStringField(ALL, place.getAddress(), Store.NO, Index.TOKENIZED));
		addField(fields, createStringField(ALL, place.getCity(), Store.NO, Index.TOKENIZED));
		addField(fields, createStringField(ALL, place.getUser().getLoginName(), Store.NO, Index.TOKENIZED));
		addField(fields, createStringField(ALL, place.getUser().getFirstname(), Store.NO, Index.TOKENIZED));
		addField(fields, createStringField(ALL, place.getUser().getLastname(), Store.NO, Index.TOKENIZED));
		for (Category category : place.getCategories()) {
			addField(fields, createStringField(ALL, category.getName(), Store.NO, Index.TOKENIZED));
		}
		
		return addFieldsToDocument(fields);
	}

	private boolean addFieldsToDocument(List<Field> fields) {
		if (fields.size() == 0)
			return false;

		for (Field field : fields) {
			document.add(field);
		}

		return true;
	}

	private boolean addField(List<Field> fields, Field field) {
		if (field == null)
			return false;

		fields.add(field);
		return true;
	}

	private Field createDocumentIDField() {
		return new Field(ID, String.valueOf(place.getId()), Store.YES, Index.UN_TOKENIZED);
	}

	private Field createStringField(String fieldName, String value, Store store, Index index) {
		if (value == null)
			return null;

		return new Field(fieldName, value, store, index);
	}
}
